package com.db.httpserver;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.params.HttpMethodParams;

public class Test {
    private static String url = "http://localhost:8080/";

    final AtomicInteger nErrors = new AtomicInteger();
    final static int N_THREADS = 100;
    final static int N_ITERS = 100;
    final CountDownLatch latch = new CountDownLatch(N_THREADS);
    
    public static void main(String[] args) throws InterruptedException {
        Test test = new Test();
        
        long begin = System.nanoTime();
        
        for (int i = 0; i < N_THREADS; ++i) {
            test.new ClientThread().start();
        }
        
        test.latch.await();
        
        long time = System.nanoTime() - begin;
        
        System.out.println("count of threads: " + N_THREADS);
        System.out.println("count of iters: " + N_ITERS);
        System.out.println("expected count of total gets: " + N_THREADS * N_ITERS);
        System.out.println("count of errors: " + test.nErrors);
        System.out.println("real count of total processed gets: " + (N_THREADS * N_ITERS - test.nErrors.get()));
        System.out.println("average process speed: " + Math.pow(10.0, 9.0) * (N_THREADS * N_ITERS - test.nErrors.get()) / time + " requests per sec");
    }

    public class ClientThread extends Thread {

        @Override
        public void run() {
            // Create an instance of HttpClient.
            HttpClient client = new HttpClient();

            // Create a method instance.
            GetMethod method = new GetMethod(url);

            // Provide custom retry handler is necessary
            method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                    new DefaultHttpMethodRetryHandler(3, false));

            try {
                for (int i = 0; i < N_ITERS; ++i) {
                    try {
                        // Execute the method.
                        int statusCode = client.executeMethod(method);
    
                        if (statusCode != HttpStatus.SC_OK) {
                            System.err.println("Method failed: "
                                    + method.getStatusLine());
                        }
    
                        // Read the response body.
                        byte[] responseBody = method.getResponseBody();
    
                        // Deal with the response.
                        // Use caution: ensure correct character encoding and is not
                        // binary
                        // data
                        System.out.println(new String(responseBody));
                    } catch (HttpException e) {
                    /*                System.err.println("Fatal protocol violation: "
                                            + e.getMessage());
                                    e.printStackTrace();*/
                        nErrors.incrementAndGet();
                    } catch (IOException e) {
                    /*                System.err.println("Fatal transport error: " + e.getMessage());
                                    e.printStackTrace();*/
                      nErrors.incrementAndGet();
                    }
                }
            } finally {
                // Release the connection.
                method.releaseConnection();
                latch.countDown();
            }
        }

    }
}
